﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BusinessPlatform.Core.BusinessObject.Mapping;
using BusinessPlatform.Core.BusinessObject.Binding;
using BusinessPlatform.Core.BusinessObject.Properties;

namespace BusinessPlatform.Core.BusinessObject
{
    /// <summary>
    /// 业务对象基类
    /// </summary>
    public abstract class BusinessObjectBase : BindableBase, IBusinessObjectBase, IBusinessObjectProperties, IBusinessObjectStatus
    {
        public BusinessObjectBase()
        {
            //注册属性
            PropertiesManager.RegisterProperties(this);
            _Status = BusinessObjectStatusEnumType.NewMode;
            this.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(BusinessObjectBase_PropertyChanged);
        }

        void BusinessObjectBase_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (_Status == BusinessObjectStatusEnumType.OriginalMode)
                _Status = BusinessObjectStatusEnumType.UpdateMode;
        }

        /// <summary>
        /// 业务对象的物理表
        /// </summary>
        public abstract string TableName { get; }
        #region property setting
        private IPropertiesManager _PropertiesManager;
        /// <summary>
        /// 获取属性管理器
        /// </summary>
        internal IPropertiesManager PropertiesManager
        {
            get
            {
                if (_PropertiesManager == null)
                    _PropertiesManager = new PropertiesManager();
                return _PropertiesManager;
            }
        }
        /// <summary>
        /// 获取属性值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="PropertyValue"></param>
        /// <returns></returns>
        protected T GetPropertyValue<T>(string PropertyName)
        {
            return PropertiesManager.GetPropertyValue<T>(PropertyName);
        }
        /// <summary>
        /// 设置属性值
        /// </summary>
        /// <typeparam name="T">属性类型</typeparam>
        /// <param name="PropertyName">属性名称</param>
        /// <param name="value">新的值</param>
        protected void SetPropertyValue<T>(string PropertyName, T value)
        {
            bool IsChange = false;
            //获取属性值
            var propertyInfo = PropertiesManager.GetPropertyInfoByPropertyName(PropertyName);
            if (propertyInfo.PropertyValue == null)
                IsChange = true;
            //获取原始值
            T sourceValue = GetPropertyValue<T>(PropertyName);
            //比较两个值是否相等
            if (Object.Equals(sourceValue, value) == false)
                IsChange = true;
            if (IsChange)
            {
                //值发生变化之前
                OnPropertyChanging(PropertyName);
                //设置新的值
                PropertiesManager.SetPropertyValue<T>(PropertyName, value);
                //值发生变化之后
                OnPropertyChanged(PropertyName);
            }
        }
        #endregion

        #region Busienss Status
        private BusinessObjectStatusEnumType _Status;
        BusinessObjectStatusEnumType IBusinessObjectStatus.Status
        {
            get { return _Status; }
            set { _Status = value; }
        }
        #endregion

        public void Delete()
        {
            if (_Status == BusinessObjectStatusEnumType.NewMode)
                _Status = BusinessObjectStatusEnumType.LogicalDeleteMode;
            else
                _Status = BusinessObjectStatusEnumType.PhysicalDeleteMode;
        }

        #region PropertiesManager
        IPropertiesManager IBusinessObjectProperties.PropertiesManager
        {
            get { return PropertiesManager; }
        }

        T IBusinessObjectProperties.GetPropertyValue<T>(string PropertyName)
        {
            return this.GetPropertyValue<T>(PropertyName);
        }

        void IBusinessObjectProperties.SetPropertyValue<T>(string PropertyName, T value)
        {
            this.SetPropertyValue<T>(PropertyName, value);
        }
        #endregion
    }
}
